package com.lap.context.starter.shared;

import com.lap.framework.common.constant.Header;
import com.lap.framework.common.tool.CryptoUtil;
import jakarta.servlet.http.HttpServletRequest;
import java.util.function.Function;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

@Slf4j
@UtilityClass
public class HeaderUtil {

  public static Integer getUserId(HttpServletRequest request) {
    return getInt(request, Header.USER_ID, Constant.USER_ID);
  }

  public static String getUserName(HttpServletRequest request) {
    return getStr(request, Header.USER_NAME, Constant.SYSTEM_USER);
  }

  public static String getFullName(HttpServletRequest request) {
    return getStr(request, Header.FULL_NAME, true, Constant.SYSTEM_USER);
  }

  /** 获取字符串值 */
  public static String getStr(HttpServletRequest request, String key, String defaultValue) {
    return getStr(request, key, false, defaultValue);
  }

  /** 获取字符串值（可解码） */
  public static String getStr(
      HttpServletRequest request, String key, boolean decode, String defaultValue) {
    return getValue(request, key, Function.identity(), decode, defaultValue);
  }

  /** 获取整数值 */
  public static Integer getInt(HttpServletRequest request, String key, Integer defaultValue) {
    return getValue(request, key, Integer::valueOf, false, defaultValue);
  }

  /** 获取长整型值 */
  public static Long getLong(HttpServletRequest request, String key, Long defaultValue) {
    return getValue(request, key, Long::valueOf, false, defaultValue);
  }

  /** 获取布尔值 */
  public static Boolean getBool(HttpServletRequest request, String key, Boolean defaultValue) {
    return getValue(request, key, Boolean::valueOf, false, defaultValue);
  }

  /**
   * 获取Request 头信息
   *
   * @param request HttpServletRequest
   * @param key 请求头或属性的 key
   * @param converter 字符串转换函数，如 Integer::valueOf
   * @param decode 是否先解码
   * @param <T> 返回值类型
   * @return 转换后的值或 null
   */
  private static <T> T getValue(
      HttpServletRequest request,
      String key,
      Function<String, T> converter,
      boolean decode,
      T defaultValue) {
    if (StringUtils.isBlank(key)) {
      return defaultValue;
    }

    String originValue = request.getHeader(key);
    if (StringUtils.isBlank(originValue)) {
      originValue = (String) request.getAttribute(key);
    }

    if (StringUtils.isBlank(originValue)) {
      return defaultValue;
    }

    if (decode) {
      originValue = CryptoUtil.uriDecode(originValue);
    }

    try {
      return converter.apply(originValue);
    } catch (Exception e) {
      log.warn("Header key [ {} ] value [ {} ] conversion failed", key, originValue);
      return defaultValue;
    }
  }
}
